package com.amap.sign.impl;

import com.amap.constants.Constants;
import com.amap.exception.AmapSignException;
import com.amap.sign.SignVerifier;
import com.amap.utils.SignUtils;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
 * @author liuyi
 * @since 2025/10/31 11:15
 */

public class DefaultSignVerifier implements SignVerifier {
    private final String amapPublicKey;

    public DefaultSignVerifier(String amapPublicKey) {
        if (StringUtils.isEmpty(amapPublicKey)) {
            throw new IllegalArgumentException("高德公钥不能为空，请从高德云店页面获取");
        } else {
            this.amapPublicKey = amapPublicKey;
        }
    }

    @Override
    public void verify(Map<String, String> requestMap) {
        try {
            String sign = (String)requestMap.get(Constants.PARAM_SIGN);
            if (StringUtils.isEmpty(sign)) {
                throw new AmapSignException(Constants.ERROR_SIGN_MISSING, "验签失败：请求中未包含sign参数");
            } else {
                String signContent = SignUtils.buildSignContent(requestMap);
                byte[] publicKeyBytes = SignUtils.decodeBase64(this.amapPublicKey);
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PublicKey publicKey = keyFactory.generatePublic(keySpec);
                Signature signature = Signature.getInstance("SHA256WithRSA");
                signature.initVerify(publicKey);
                signature.update(signContent.getBytes(StandardCharsets.UTF_8));
                boolean verifyResult = signature.verify(SignUtils.decodeBase64(sign));
                if (!verifyResult) {
                    throw new AmapSignException(Constants.ERROR_SIGN_VERIFY_FAILED, "RSA2验签失败：sign与待签内容不匹配");
                }
            }
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new AmapSignException(Constants.ERROR_PUBLIC_KEY_INVALID, "高德公钥无效（格式错误或算法不支持）", e);
        } catch (SignatureException | InvalidKeyException e) {
            throw new AmapSignException(Constants.ERROR_SIGN_VERIFY_FAILED, "RSA2验签过程异常", e);
        }
    }
}